#include "WeatherUtil.h"
#include "OCMain/FileUtil.h"
#include "drogon/drogon.h"
#include "OCMain/sqlite3/sqlite3pp.h"

StringVector WeatherUtil::listFileWithExt(String path, String ext)
{
	StringVector results;

	StringVector sv1 = FileUtil::findFiles(path);

	std::copy_if(sv1.begin(), sv1.end(), std::inserter(results, results.end()), [&ext](String name) {
		return StringUtil::endsWith(name, ext, false);
	});

	return results;
}

StringVector WeatherUtil::listSubDir(String path)
{
	StringVector results;

	StringVector sv1 = FileUtil::findFiles(path);

	std::copy_if(sv1.begin(), sv1.end(), std::inserter(results, results.end()), [&path](String name) {
		return name != "." && name != ".." && FileUtil::typeOfFile(path + "/" + name) == FileUtil::DIRECTORY;
		});

	return results;
}

void WeatherUtil::removeDir(String path)
{
	StringVector files = FileUtil::findFiles(path);

	for (auto file : files)
	{
		if (file == "." || file == "..") continue;
		String fileName = path + "/" + file;
		if (FileUtil::typeOfFile(fileName) == FileUtil::REGULAR_FILE)
		{
			FileUtil::deleteFile(fileName);
		}
		else
		{
			removeDir(fileName);
		}
	}

	FileUtil::deletFolder(path);
}

String WeatherUtil::getDateUTC(int before)
{
#if 0
	return "20230728";
#endif 
	OCPP::Date date = OCPP::Date::now();
	date = date.after(-before * 24 * 3600);
	return date.toCustomedFormattedString("%Y%m%d");
}

std::shared_ptr<sqlite3pp::database> WeatherUtil::getOrCreateSqlite(String fileName)
{
	String sql = "CREATE TABLE IF NOT EXISTS data(\
		id BIGINT PRIMARY KEY,\
		name TEXT,\
		desr TEXT,\
		created TIMESTAMP DEFAULT(DATETIME('now', 'localtime')))";

	try {
		std::shared_ptr<sqlite3pp::database> db = std::make_shared<sqlite3pp::database>(fileName.c_str());
		if (db->execute(sql.c_str()) == SQLITE_OK)
		{
			return db;
		}
	}
	catch (sqlite3pp::database_error ex)
	{
		LOG_ERROR << ex.what() << "\n";
	}
	return nullptr;
}

bool WeatherUtil::exist(std::shared_ptr<sqlite3pp::database> db, String name)
{
	String sql = str_format("SELECT COUNT(*) FROM data WHERE name = '%s'", StringUtil::ANSIToUTF8(name).c_str());
	try {
		sqlite3pp::query qry(*db, sql.c_str());
		int n = (*qry.begin()).get<int>(0);
		return n > 0;
	}
	catch (sqlite3pp::database_error ex)
	{
		LOG_ERROR << ex.what() << "\n";
	}

	return false;
}

bool WeatherUtil::insert(std::shared_ptr<sqlite3pp::database> db, String name)
{
	try {
		sqlite3pp::command cmd(
			*db, "INSERT INTO data (name) VALUES (?)");
		cmd.binder() << StringUtil::ANSIToUTF8(name);
		return cmd.execute() == SQLITE_OK;
	}
	catch (sqlite3pp::database_error ex)
	{
		LOG_ERROR << ex.what() << "\n";
	}

	return false;
}

bool WeatherUtil::insert(std::shared_ptr<sqlite3pp::database> db, String name, String time)
{
	try {
		sqlite3pp::command cmd(
			*db, "INSERT INTO data (name,created) VALUES (?,?)");
		cmd.binder() << StringUtil::ANSIToUTF8(name) << time;
		return cmd.execute() == SQLITE_OK;
	}
	catch (sqlite3pp::database_error ex)
	{
		LOG_ERROR << ex.what() << "\n";
	}

	return false;
}

void WeatherUtil::createDBClient(String fileName,String name)
{
	drogon::app().createDbClient("sqlite3", "", 0, "", "", "",1, fileName, name);
}

const String WeatherUtil::formatTime(time_t t)
{
	Date date(t * MICRO_SECONDS_PRE_SEC);
	return date.toCustomedFormattedStringLocal("%Y%m%d%H%M%S",false);
}

const time_t WeatherUtil::toTimeTick(String timeStr)
{
	Date date(
		std::atoi(timeStr.substr(0, 4).c_str()),
		std::atoi(timeStr.substr(4, 2).c_str()),
		std::atoi(timeStr.substr(6, 2).c_str()),
		std::atoi(timeStr.substr(8, 2).c_str()),
		std::atoi(timeStr.substr(10, 2).c_str()),
		std::atoi(timeStr.substr(12, 2).c_str())
		);
	return date.secondsSinceEpoch();
}
